package base.thread_demo.demo11;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程通信案例:
 */
public class CommunicationDemo4 {
    private static final Logger log = LoggerFactory.getLogger(CommunicationDemo4.class);

    static boolean hasCigarette = false;//没香烟
    static boolean hasTakeout = false;//没外卖
    static ReentrantLock ROOM = new ReentrantLock();
    // 等烟休息室
    static Condition waitCigaretteSet = ROOM.newCondition();
    // 等外卖休息室
    static Condition waitTakeoutSet = ROOM.newCondition();

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            log.info("{}：有没有烟？[{}]", Thread.currentThread().getName(), hasCigarette);

            ROOM.lock();
            try {
                while(!hasCigarette) {
                    log.info("{}：没烟啊，那先歇会", Thread.currentThread().getName());
                    waitCigaretteSet.await();// 注意是 await() 方法，别调用成wait了
                }
                log.info("{}可以干活了", Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                ROOM.unlock();
            }
        },"小南").start();

        new Thread(()->{
            log.info("{}：有没有外卖？[{}]", Thread.currentThread().getName(), hasTakeout);

            ROOM.lock();
            try {
                while(!hasTakeout) {
                    log.info("{}：没有外卖啊，那先歇会", Thread.currentThread().getName());
                    waitTakeoutSet.await();
                }
                log.info("{}可以干活了", Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                ROOM.unlock();
            }
        },"小女").start();

        Thread.sleep(1000);

        // 负责唤醒他们
        new Thread(()->{
            ROOM.lock();
            try {
                log.info("{}：香烟到了噢！", Thread.currentThread().getName());
                hasCigarette = true;
                waitCigaretteSet.signal();
            } finally {
                ROOM.unlock();
            }
        },"送烟的").start();

        Thread.sleep(1000);

        new Thread(()->{
            ROOM.lock();
            try {
                log.info("{}：外卖到了噢！", Thread.currentThread().getName());
                hasTakeout = true;
                waitTakeoutSet.signal();
            } finally {
                ROOM.unlock();
            }
        },"送外卖的").start();
    }

}
